package drds.plus.sql_process.utils.range;

import com.google.common.collect.Lists;
import drds.plus.sql_process.abstract_syntax_tree.expression.item.Item;
import drds.plus.sql_process.abstract_syntax_tree.expression.item.function.BooleanFilter;
import drds.plus.sql_process.abstract_syntax_tree.expression.item.function.Filter;
import drds.plus.sql_process.abstract_syntax_tree.expression.item.function.OrsFilter;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class AndRangeProcessor extends AbstractRangeProcessor {

    private final Comparable column;
    /**
     * 其他不符合rang的条件
     */
    private final List<Filter> filterList = new ArrayList();
    boolean emptySet = false;
    private Range range = null;

    public AndRangeProcessor(Comparable column) {
        this.column = column;
    }

    public boolean process(Filter filter) {
        if (filter != null && filter instanceof OrsFilter) {
            // 不处理group filter
            filterList.add(filter);
            return true;
        }

        if (filter != null && ((BooleanFilter) filter).getValue() instanceof Item) {
            // 不处理column = column的filter
            filterList.add(filter);
            return true;
        }

        if (!(((BooleanFilter) filter).getColumn() instanceof Item)) {
            // 不处理value=value的filter
            filterList.add(filter);
            return true;
        }

        Range range = getRange(filter);
        // 类似like noteq等操作符
        if (range == null) {
            filterList.add(filter);
            return true;
        }

        if (this.range == null) {
            this.range = range;
            return true;
        }

        // 若有交集，则交
        // 否则为空集，直接返回
        if (this.range.intersects(range)) {
            this.range = this.range.intersect(range);
            return true;
        } else {
            emptySet = true;
            return false;
        }

    }

    public List<Filter> toFilterList() {
        if (this.emptySet) {
            return Lists.newLinkedList();
        }

        List<Filter> filterList = new LinkedList();
        filterList.addAll(this.filterList);
        filterList.addAll(buildFilterList(range, column));
        return filterList;
    }
}
